package com.hopechart.micro.common.generator.repository;

import com.hopechart.micro.common.exception.BusinessException;
import com.hopechart.micro.common.exception.ErrorCode;
import com.hopechart.micro.common.generator.AbstractGenerator;
import com.hopechart.micro.config.MasterDataSourceConfig;
import com.hopechart.micro.util.StringUtil;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * @author daijiang@hopechart.com
 */
public class RepositoryGenerator extends AbstractGenerator {

    private static final Logger log = LoggerFactory.getLogger(RepositoryGenerator.class);

    public void execute(MasterDataSourceConfig dataSourceConfig, String tableName, String modelName) {
        if(StringUtil.isEmpty(modelName)) {
            modelName = tableNameConvertUpperCamel(tableName);
        }
        config(dataSourceConfig.getUsername(), dataSourceConfig.getPassword(),
                dataSourceConfig.getUrl(), dataSourceConfig.getDriverClassName(),
                tableName, modelName);

        List<String> warnings = new ArrayList<String>();
        boolean overwrite = true;
        try {
            ConfigurationParser cp = new ConfigurationParser(warnings);
            InputStream is = getClass().getClassLoader().getResourceAsStream(
                    "com/hopechart/micro/common/generator/repository/generatorConfig.xml");
            Configuration config = cp.parseConfiguration(is);
            DefaultShellCallback callback = new DefaultShellCallback(overwrite);
            MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
            myBatisGenerator.generate(null);
        } catch (Exception e) {
            log.error("持久层代码生成异常，{}", e.getMessage(), e);
            throw new BusinessException(ErrorCode.GEN_RESP, "持久层代码生成异常，" + e.getMessage(), e);
        }

        if (warnings.size() == 0) {
            log.info("{}.java 生成成功.", modelName);
            log.info("{}Mapper.java 生成成功.", modelName);
            log.info("{}Mapper.xml 生成成功.", modelName);
        } else {
            throw new BusinessException(ErrorCode.GEN_RESP, "持久层代码生成异常，" + appendWarning(warnings));
        }
    }

    private String appendWarning(List<String> warnings) {
        StringBuffer warningBuf = new StringBuffer();
        for (String warning : warnings) {
            warningBuf.append(warning).append("\n");
        }
        return warningBuf.toString();
    }

    public void config(String dbUser, String dbUserPass, String url, String driverClass, String tableName,
                       String modelName) {

        System.setProperty("mapper.plugin", "com.hopechart.micro.common.generator.mapper.MapperPlugin");
        System.setProperty("mapper.Mapper", "com.hopechart.micro.common.generator.mapper.MyMapper");

        System.setProperty("jdbc.driverClass", driverClass);
        System.setProperty("jdbc.url", url);
        System.setProperty("jdbc.user", dbUser);
        System.setProperty("jdbc.password", dbUserPass);

        System.setProperty("pojo.pkg.name", getPojoPackage());
        System.setProperty("pojo.save.path", PROJECT_PATH + JAVA_PATH);

        System.setProperty("mapperxml.pkg.name", "mapper.master");
        System.setProperty("mapperxml.save.path", PROJECT_PATH + RESOURCES_PATH);

        System.setProperty("mapper.pkg.name", getMapperPackage());
        System.setProperty("mapper.save.path", PROJECT_PATH + JAVA_PATH);

        System.setProperty("table.name", tableName);
        System.setProperty("entity.name", modelName);

        printProperties();
    }

    private void printProperties() {

        log.info("DB Url: {}", System.getProperty("jdbc.url"));
        log.info("DB User: {}", System.getProperty("jdbc.user"));
        log.info("DB Password: {}", System.getProperty("jdbc.password"));

        log.info("User Root: {}", PROJECT_PATH.replace(File.separator, "/"));
        log.info("Model Package: {}", System.getProperty("pojo.pkg.name"));
        log.info("Mapper Package: {}", System.getProperty("mapper.pkg.name"));
        log.info("Table Name: {}", System.getProperty("table.name"));
        log.info("POJO Name: {}", System.getProperty("entity.name"));

        log.info("POJO Save Path: {}", System.getProperty("pojo.save.path").replace(File.separator, "/"));
        log.info("Mapper Save Path: {}", System.getProperty("mapper.save.path").replace(File.separator, "/"));
        log.info("Mapper XML Save Path: {}", System.getProperty("mapperxml.save.path").replace(File.separator, "/"));
    }
}
